#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <semaphore.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
#include "csapp.h"
#include "gestionSocket.h"
#include "gestionNcurses.h"

#define TRUE 1
#define FALSE 0
#define MAX_CHAT_STR_LEN 100


//#######################################
//#
//# Definition des structures
//#
struct infoMembre
{				
	int identifiant; 		
	char ptrNick[MAX_CHAT_STR_LEN];
	char ptrGroupe[MAX_CHAT_STR_LEN];
	int fd;
	unsigned int pid;					
};								 

struct suppressionMembre
{						
	char ptrNick[MAX_CHAT_STR_LEN];
	char ptrGroupe[MAX_CHAT_STR_LEN];
	unsigned int pid;
	int fd;					
};

struct noeud
{			
	struct infoMembre membre;		
	struct noeud* suivant;
	sem_t sem;	
};	

struct threadNode
{
	pthread_t thread;
	struct threadNode* suivant;
};

struct paramsIntervalle
{
	int debut;
	int fin;
	unsigned int pid;
	int fd;
};

struct paramsTexte
{
	char ptrNick[MAX_CHAT_STR_LEN];
	char ptrGroupe[MAX_CHAT_STR_LEN];
	char ptrTexte[MAX_CHAT_STR_LEN];
	unsigned int pid;
};

struct paramQuit
{
	unsigned int pid;
};
	
//#######################################
//#
//# Definition des fonctions
//#
void* executeTransCHAT(void* newClientFD);

//Gestion listeChainee
struct noeud * findPrevCHAT(const char* ptrNick, const char* ptrGroupe);
void* addItemCHAT(void* membre);
void* modifyItemCHAT(void* membre);
void* removeItemCHAT(void* membre);
void* listItemsCHAT(void* intervalle);
void* quitUser(void* paramQuit);
void* transTextCHAT(void* message);

//Gestion communication
void sendMessage(int fdClient, char ack, char message[MESSAGE_SIZE]);
void broadcastAll(char ack, char message[MESSAGE_SIZE]);
void broadcastAllExceptSelf(char ack, char message[MESSAGE_SIZE], unsigned int selfPid);
void broadcastAllInGroup(char ack, char message[MESSAGE_SIZE], unsigned int selfPid, char groupe[100]);
void broadcastMessage(char ack, char message[MESSAGE_SIZE], int toSelf, unsigned int selfPid, int toGroup, char groupe[100]);

//Gestion liste threads
void initThreadNode(struct threadNode** head, struct threadNode** tail);
